import React, { useState, useEffect, useRef } from 'react';
import { AppScreen, GameSettings, ApiChannel, ModelConfig, AiCallMode, ModelPurpose } from '../types';
import { loadSettings, saveSettings } from '../services/gameSaveService';
import { DEFAULT_MAX_HISTORY_LENGTH, DEFAULT_API_KEY_PLACEHOLDER, DEFAULT_MODEL_TEMPERATURE, DEFAULT_MODEL_MAX_TOKENS, DEFAULT_REQUEST_TIMEOUT } from '../constants';
import Modal from './Modal';
import { v4 as uuidv4 } from 'uuid';
import CollapsibleSection from './CollapsibleSection';
import LoadingSpinner from './LoadingSpinner';

interface SettingsScreenProps {
  setCurrentScreen: (screen: AppScreen) => void;
  onSettingsChange: (settings: GameSettings) => void;
  showToast: (message: string, type?: 'success' | 'error') => void;
  onBack: () => void;
  cameFromGame: boolean;
}

const TrashIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" {...props}>
    <path strokeLinecap="round" strokeLinejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12.56 0c1.153 0 2.243.09 3.288.255A1.037 1.037 0 017.38 7.608l-.292 2.917A2.25 2.25 0 009.796 13.5h4.408a2.25 2.25 0 002.208-2.975l-.292-2.917a1.037 1.037 0 01.375-1.055M12 12V4.5m0 7.5V4.5m0 7.5H4.5m7.5 0h7.5" />
  </svg>
);
const PencilIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" {...props}>
    <path strokeLinecap="round" strokeLinejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" />
  </svg>
);
const StarIconSolid: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" {...props}>
        <path fillRule="evenodd" d="M10.788 3.21c.448-1.077 1.976-1.077 2.424 0l2.082 5.007 5.404.433c1.164.093 1.636 1.545.749 2.305l-4.117 3.527 1.257 5.273c.271 1.136-.964 2.033-1.96 1.425L12 18.354l-4.543 2.86c-.996.608-2.231-.29-1.96-1.425l1.257-5.273-4.117-3.527c-.887-.76-.415-2.212.749-2.305l5.404-.433 2.082-5.006z" clipRule="evenodd" />
    </svg>
);
const StarIconOutline: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" {...props}>
        <path strokeLinecap="round" strokeLinejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.321l5.588.512a.563.563 0 01.309.988l-4.04 3.473a.563.563 0 00-.18.537l1.205 5.378a.563.563 0 01-.84.61l-4.93-2.913a.563.563 0 00-.606 0l-4.93 2.913a.563.563 0 01-.84-.61l1.205-5.378a.563.563 0 00-.18-.537l-4.04-3.473a.563.563 0 01.309-.988l5.588-.512a.562.562 0 00.475-.321L11.48 3.5z" />
    </svg>
);

const ArrowDownTrayIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" {...props}>
    <path strokeLinecap="round" strokeLinejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3" />
  </svg>
);
const ArrowUpTrayIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" {...props}>
    <path strokeLinecap="round" strokeLinejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5" />
  </svg>
);

const modelPurposeOptions: { value: ModelPurpose; label: string }[] = [
    { value: 'general', label: '通用' },
    { value: 'narrative', label: '叙事图片' },
    { value: 'avatar', label: '角色头像' },
    { value: 'map', label: '地图/场景图' },
    { value: 'hybrid-planning', label: '混合-规划' },
    { value: 'hybrid-narrative', label: '混合-叙事' },
    { value: 'hybrid-status', label: '混合-状态' },
];


const SettingsScreen: React.FC<SettingsScreenProps> = ({ setCurrentScreen, onSettingsChange, showToast, onBack, cameFromGame }) => {
  const [settings, setSettings] = useState<GameSettings | null>(null);
  
  const [isChannelModalOpen, setIsChannelModalOpen] = useState(false);
  const [editingChannel, setEditingChannel] = useState<ApiChannel | null>(null);
  const [currentChannelForm, setCurrentChannelForm] = useState<Partial<ApiChannel>>({});

  const [isModelModalOpen, setIsModelModalOpen] = useState(false);
  const [editingModel, setEditingModel] = useState<ModelConfig | null>(null);
  const [currentModelForm, setCurrentModelForm] = useState<Partial<ModelConfig>>({});
  
  const apiConfigFileInputRef = useRef<HTMLInputElement>(null);


  useEffect(() => {
    const fetchSettings = async () => {
        const loaded = await loadSettings();
        if (!loaded.aiCallMode) { 
            loaded.aiCallMode = AiCallMode.Hybrid; 
        }
        setSettings(loaded);
    };
    fetchSettings();
  }, []);

  const handleSaveSettings = async () => {
    if (!settings) return;
    if (settings.apiChannels.some(c => !c.name || !c.baseUrl || !c.apiKey || c.apiKey === DEFAULT_API_KEY_PLACEHOLDER)) {
      showToast("所有API渠道必须填写名称、Base URL和有效的API密钥。", "error");
      return;
    }
    if (settings.modelConfigs.some(m => !m.displayName || !m.apiModelName || !m.apiChannelId || m.temperature === undefined || m.maxTokens === undefined || !m.purpose)) {
      showToast("所有模型必须填写显示名称、API模型名称、关联API渠道、用途，并设置温度和最大Token数。", "error");
      return;
    }
    if (settings.modelConfigs.length > 0 && !settings.defaultTextModelId) {
        showToast("请至少选择一个默认的文本生成模型。", "error");
        return;
    }
     if (settings.maxHistoryLengthToDisplay < 1 || settings.maxHistoryLengthToDisplay > 50) {
        showToast("最大历史记录长度必须在 1 到 50 之间。", "error");
        return;
    }
    if (settings.requestTimeout < 5000 || settings.requestTimeout > 120000) {
        showToast("请求超时时间必须在 5000 到 120000 毫秒之间。", "error");
        return;
    }

    await saveSettings(settings);
    onSettingsChange(settings);
    showToast("设置已保存！", "success");
  };

  // API Channel Management
  const openNewChannelModal = () => {
    setEditingChannel(null);
    setCurrentChannelForm({ name: '', baseUrl: '', apiKey: '' });
    setIsChannelModalOpen(true);
  };

  const openEditChannelModal = (channel: ApiChannel) => {
    setEditingChannel(channel);
    setCurrentChannelForm({ ...channel });
    setIsChannelModalOpen(true);
  };

  const handleChannelFormChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setCurrentChannelForm({ ...currentChannelForm, [e.target.name]: e.target.value });
  };

  const handleSaveChannel = () => {
    if (!currentChannelForm.name || !currentChannelForm.baseUrl || !currentChannelForm.apiKey) {
      showToast("渠道名称、Base URL和API密钥不能为空。", "error");
      return;
    }
    setSettings(prev => {
        if (!prev) return null;
      const newChannels = [...prev.apiChannels];
      if (editingChannel) { // Edit
        const index = newChannels.findIndex(c => c.id === editingChannel.id);
        if (index > -1) newChannels[index] = { ...editingChannel, ...currentChannelForm } as ApiChannel;
      } else { // Add
        newChannels.push({ id: uuidv4(), ...currentChannelForm } as ApiChannel);
      }
      return { ...prev, apiChannels: newChannels };
    });
    setIsChannelModalOpen(false);
    showToast(`API渠道 "${currentChannelForm.name}" 已${editingChannel ? '更新' : '添加'}。`, "success");
  };

  const handleDeleteChannel = (channelId: string) => {
    if (!settings) return;
    if (settings.modelConfigs.some(m => m.apiChannelId === channelId)) {
      showToast("无法删除此API渠道，因为它仍被一个或多个模型使用。", "error");
      return;
    }
    setSettings(prev => (prev ? {
      ...prev,
      apiChannels: prev.apiChannels.filter(c => c.id !== channelId)
    } : null));
    showToast("API渠道已删除。", "success");
  };

  // Model Management
  const openNewModelModal = () => {
    if (!settings) return;
    setEditingModel(null);
    setCurrentModelForm({
      displayName: '',
      apiModelName: '',
      apiChannelId: settings.apiChannels[0]?.id || '', 
      temperature: DEFAULT_MODEL_TEMPERATURE,
      maxTokens: DEFAULT_MODEL_MAX_TOKENS,
      purpose: 'general', // Default purpose
    });
    setIsModelModalOpen(true);
  };

  const openEditModelModal = (model: ModelConfig) => {
    setEditingModel(model);
    setCurrentModelForm({ ...model, purpose: model.purpose || 'general' });
    setIsModelModalOpen(true);
  };
  
  const handleModelFormChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
    const { name, value } = e.target;
    const isNumeric = name === 'temperature' || name === 'maxTokens';
    setCurrentModelForm({ ...currentModelForm, [name]: isNumeric ? parseFloat(value) : value });
  };

  const handleSaveModel = () => {
    if (!currentModelForm.displayName || !currentModelForm.apiModelName || !currentModelForm.apiChannelId || currentModelForm.temperature === undefined || currentModelForm.maxTokens === undefined || !currentModelForm.purpose) {
      showToast("请填写所有模型字段，包括用途。", "error");
      return;
    }
    if (currentModelForm.temperature < 0 || currentModelForm.temperature > 2) {
      showToast("温度值应在0到2之间。", "error");
      return;
    }
    if (currentModelForm.maxTokens < 1) {
      showToast("最大Token数必须大于0。", "error");
      return;
    }

    setSettings(prev => {
        if (!prev) return null;
      const newModels = [...prev.modelConfigs];
      if (editingModel) { // Edit
        const index = newModels.findIndex(m => m.id === editingModel.id);
        if (index > -1) newModels[index] = { ...editingModel, ...currentModelForm } as ModelConfig;
      } else { // Add
        newModels.push({ id: uuidv4(), ...currentModelForm } as ModelConfig);
      }
      return { ...prev, modelConfigs: newModels };
    });
    setIsModelModalOpen(false);
    showToast(`模型 "${currentModelForm.displayName}" 已${editingModel ? '更新' : '添加'}。`, "success");
  };

  const handleDeleteModel = (modelId: string) => {
    setSettings(prev => {
      if (!prev) return null;
      const newModels = prev.modelConfigs.filter(m => m.id !== modelId);
      let newDefaultTextModelId = prev.defaultTextModelId;
      let newDefaultNarrativeImageModelId = prev.defaultNarrativeImageModelId;
      let newDefaultHybridPlanningModelId = prev.defaultHybridPlanningModelId;
      let newDefaultHybridNarrativeModelId = prev.defaultHybridNarrativeModelId;
      let newDefaultHybridStatusModelId = prev.defaultHybridStatusModelId;
      
      if (prev.defaultTextModelId === modelId) newDefaultTextModelId = null;
      if (prev.defaultNarrativeImageModelId === modelId) newDefaultNarrativeImageModelId = null;
      if (prev.defaultHybridPlanningModelId === modelId) newDefaultHybridPlanningModelId = null;
      if (prev.defaultHybridNarrativeModelId === modelId) newDefaultHybridNarrativeModelId = null;
      if (prev.defaultHybridStatusModelId === modelId) newDefaultHybridStatusModelId = null;

      
      const updatedSettings = { 
          ...prev, 
          modelConfigs: newModels, 
          defaultTextModelId: newDefaultTextModelId, 
          defaultNarrativeImageModelId: newDefaultNarrativeImageModelId,
          defaultHybridPlanningModelId: newDefaultHybridPlanningModelId,
          defaultHybridNarrativeModelId: newDefaultHybridNarrativeModelId,
          defaultHybridStatusModelId: newDefaultHybridStatusModelId
      };
      
      if (prev.defaultTextModelId === modelId && newDefaultTextModelId === null) {
        showToast("默认文本模型已被删除，请重新选择一个。", "error")
      }
      return updatedSettings;
    });
    showToast("模型已删除。", "success");
  };

  const setDefaultTextModel = (modelId: string) => {
    setSettings(prev => (prev ? { ...prev, defaultTextModelId: modelId } : null));
    showToast(`模型已设为默认文本模型。`, "success");
  };
  
  const handleSettingsFieldChange = (field: keyof GameSettings, value: any) => {
    setSettings(prev => (prev ? { ...prev, [field]: value } : null));
  };
  
  const handleHybridModeCheckboxChange = (field: 'enableCalculationHelperAi' | 'enableFunctionCallingMode', checked: boolean) => {
    setSettings(prev => {
        if (!prev) return null;
        let helperAi = prev.enableCalculationHelperAi;
        let funcCall = prev.enableFunctionCallingMode;

        if (field === 'enableCalculationHelperAi') {
            helperAi = checked;
            if (checked) funcCall = false; // Uncheck the other
        } else {
            funcCall = checked;
            if (checked) helperAi = false; // Uncheck the other
        }
        
        return {
            ...prev,
            enableCalculationHelperAi: helperAi,
            enableFunctionCallingMode: funcCall,
        };
    });
  };


  const handleExportApiConfigs = () => {
    if (!settings) return;
    const apiConfigs = {
      apiChannels: settings.apiChannels,
      modelConfigs: settings.modelConfigs,
    };
    const filename = `jrpg_api_configs_${new Date().toISOString().slice(0,10)}.json`;
    const jsonStr = JSON.stringify(apiConfigs, null, 2);
    const blob = new Blob([jsonStr], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
    showToast("API 配置已导出!", "success");
  };

  const triggerImportApiConfigs = () => {
    apiConfigFileInputRef.current?.click();
  };

  const handleImportApiConfigsFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      const reader = new FileReader();
      reader.onload = (e) => {
        try {
          const text = e.target?.result as string;
          const imported = JSON.parse(text);
          if (Array.isArray(imported.apiChannels) && Array.isArray(imported.modelConfigs)) {
            const newApiChannels: ApiChannel[] = imported.apiChannels.filter((c: any) => c.id && c.name && c.baseUrl && c.apiKey);
            const newModelConfigs: ModelConfig[] = imported.modelConfigs
                .filter((m: any) => m.id && m.displayName && m.apiModelName && m.apiChannelId && m.temperature !== undefined && m.maxTokens !== undefined)
                .map((m: any) => ({ ...m, purpose: m.purpose || 'general' })); // Ensure purpose exists

            setSettings(prev => {
              if (!prev) return null;
              let newDefaultTextModelId = prev.defaultTextModelId;
              let newDefaultNarrativeImageModelId = prev.defaultNarrativeImageModelId;

              if (newDefaultTextModelId && !newModelConfigs.find(m => m.id === newDefaultTextModelId)) {
                newDefaultTextModelId = null;
                showToast("原默认文本模型在导入的配置中不存在，已被重置。", "error");
              }
              if (newDefaultNarrativeImageModelId && !newModelConfigs.find(m => m.id === newDefaultNarrativeImageModelId)) {
                newDefaultNarrativeImageModelId = null;
                showToast("原默认叙事图片模型在导入的配置中不存在，已被重置。", "error");
              }
              
              return {
                ...prev,
                apiChannels: newApiChannels,
                modelConfigs: newModelConfigs,
                defaultTextModelId: newDefaultTextModelId,
                defaultNarrativeImageModelId: newDefaultNarrativeImageModelId,
              };
            });
            showToast("API 配置已成功导入并替换当前配置!", "success");
          } else {
            showToast("导入失败: 文件格式不正确，缺少 'apiChannels' 或 'modelConfigs' 数组。", "error");
          }
        } catch (error) {
          showToast(`导入失败: ${error instanceof Error ? error.message : "无法解析文件。"}`, "error");
        } finally {
            if (apiConfigFileInputRef.current) {
                apiConfigFileInputRef.current.value = "";
            }
        }
      };
      reader.readAsText(file);
    }
  };

  if (!settings) {
    return (
      <div className="min-h-screen flex items-center justify-center bg-gray-900">
        <LoadingSpinner text="加载设置..." />
      </div>
    );
  }

  const checkboxStyles = "w-5 h-5 rounded bg-gray-700 border-gray-600 text-blue-500 focus:ring-blue-600";
  const smallCheckboxStyles = "w-4 h-4 rounded bg-gray-700 border-gray-600 text-blue-500 focus:ring-blue-600";

  const planningModels = settings.modelConfigs.filter(m => m.purpose === 'hybrid-planning' || m.purpose === 'general');
  const narrativeModels = settings.modelConfigs.filter(m => m.purpose === 'hybrid-narrative' || m.purpose === 'general');
  const statusModels = settings.modelConfigs.filter(m => m.purpose === 'hybrid-status' || m.purpose === 'general');


  return (
    <div className="min-h-screen bg-gray-900 text-gray-100 p-4 sm:p-6 lg:p-8">
      <div className="max-w-4xl mx-auto">
        <header className="mb-8">
          <h1 className="text-3xl sm:text-4xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-purple-400 to-sky-500">设置</h1>
          <p className="text-gray-400 mt-1">管理你的API连接、模型和游戏偏好。</p>
        </header>

        <div className="space-y-8">
            <CollapsibleSection title="API 渠道管理" defaultOpen>
                <div className="space-y-3" data-guide-id="api-channels-section">
                    {settings.apiChannels.map(channel => (
                        <div key={channel.id} className="bg-gray-800 p-3 rounded-lg flex flex-col sm:flex-row justify-between items-start sm:items-center">
                            <div className="flex-grow mb-2 sm:mb-0">
                                <p className="font-semibold text-gray-100">{channel.name}</p>
                                <p className="text-xs text-gray-400 truncate max-w-xs sm:max-w-md" title={channel.baseUrl}>URL: {channel.baseUrl}</p>
                            </div>
                            <div className="flex space-x-2 flex-shrink-0">
                                <button onClick={() => openEditChannelModal(channel)} className="p-2 text-yellow-400 hover:text-yellow-300 transition-colors"><PencilIcon className="w-5 h-5"/></button>
                                <button onClick={() => handleDeleteChannel(channel.id)} className="p-2 text-red-500 hover:text-red-400 transition-colors"><TrashIcon className="w-5 h-5"/></button>
                            </div>
                        </div>
                    ))}
                    <button onClick={openNewChannelModal} className="w-full mt-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white font-semibold rounded-md shadow-sm transition-colors text-sm">添加新 API 渠道</button>
                    <div className="flex flex-col sm:flex-row gap-2 mt-2">
                         <input type="file" accept=".json" ref={apiConfigFileInputRef} onChange={handleImportApiConfigsFileChange} className="hidden" />
                         <button onClick={triggerImportApiConfigs} className="flex-1 text-center text-sm px-3 py-2 bg-green-600 hover:bg-green-700 rounded-md flex items-center justify-center gap-2"><ArrowUpTrayIcon className="w-5 h-5" /> 导入配置</button>
                         <button onClick={handleExportApiConfigs} className="flex-1 text-center text-sm px-3 py-2 bg-indigo-600 hover:bg-indigo-700 rounded-md flex items-center justify-center gap-2"><ArrowDownTrayIcon className="w-5 h-5" /> 导出配置</button>
                    </div>
                </div>
            </CollapsibleSection>
            
            <CollapsibleSection title="模型管理" defaultOpen>
                <div className="space-y-3" data-guide-id="models-section">
                     {settings.modelConfigs.map(model => {
                        const channelName = settings.apiChannels.find(c => c.id === model.apiChannelId)?.name || '未知渠道';
                        const purposeLabel = modelPurposeOptions.find(opt => opt.value === model.purpose)?.label || '通用';
                        return (
                            <div key={model.id} className="bg-gray-800 p-3 rounded-lg">
                                <div className="flex flex-col sm:flex-row justify-between items-start sm:items-center">
                                    <div className="flex-grow mb-2 sm:mb-0">
                                        <p className="font-semibold text-gray-100">{model.displayName} <span className="text-xs ml-2 px-1.5 py-0.5 bg-gray-600 rounded-full">{purposeLabel}</span></p>
                                        <p className="text-xs text-gray-400" title={model.apiModelName}>模型名: {model.apiModelName} | 渠道: {channelName}</p>
                                    </div>
                                    <div className="flex space-x-2 flex-shrink-0 self-end sm:self-center">
                                        <button onClick={() => openEditModelModal(model)} className="p-2 text-yellow-400 hover:text-yellow-300"><PencilIcon className="w-5 h-5"/></button>
                                        <button onClick={() => handleDeleteModel(model.id)} className="p-2 text-red-500 hover:text-red-400"><TrashIcon className="w-5 h-5"/></button>
                                    </div>
                                </div>
                                <div className="mt-2 pt-2 border-t border-gray-700 flex flex-wrap gap-2 items-center text-xs">
                                    <button onClick={() => setDefaultTextModel(model.id)} className={`px-2 py-1 rounded flex items-center gap-1 transition-colors ${settings.defaultTextModelId === model.id ? 'bg-yellow-500 text-white' : 'bg-gray-700 hover:bg-gray-600'}`}>
                                      {settings.defaultTextModelId === model.id ? <StarIconSolid className="w-4 h-4"/> : <StarIconOutline className="w-4 h-4"/>} 默认文本
                                    </button>
                                </div>
                            </div>
                        )
                    })}
                    {settings.apiChannels.length > 0 ? (
                        <button onClick={openNewModelModal} className="w-full mt-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white font-semibold rounded-md shadow-sm transition-colors text-sm">添加新模型</button>
                    ) : (
                        <p className="text-center text-sm text-gray-500 py-2">请先添加一个 API 渠道才能添加模型。</p>
                    )}
                </div>
            </CollapsibleSection>

            <CollapsibleSection title="通用设置" defaultOpen>
                <div className="bg-gray-800 p-4 rounded-lg space-y-4">
                    <div>
                        <label htmlFor="maxHistoryLength" className="block text-sm font-medium text-gray-300 mb-1">发送给AI的最大历史记录长度</label>
                        <input
                            type="number"
                            id="maxHistoryLength"
                            value={settings.maxHistoryLengthToDisplay}
                            onChange={(e) => handleSettingsFieldChange('maxHistoryLengthToDisplay', parseInt(e.target.value, 10) || 0)}
                            className="w-full p-2 bg-gray-700 rounded-md"
                            min="1"
                            max="50"
                        />
                    </div>
                     <div>
                        <label htmlFor="requestTimeout" className="block text-sm font-medium text-gray-300 mb-1">API 请求超时 (毫秒)</label>
                        <input
                            type="number"
                            id="requestTimeout"
                            value={settings.requestTimeout}
                            onChange={(e) => handleSettingsFieldChange('requestTimeout', parseInt(e.target.value, 10) || 0)}
                            className="w-full p-2 bg-gray-700 rounded-md"
                            min="5000"
                            max="120000"
                            step="1000"
                        />
                    </div>
                    <div>
                        <label htmlFor="corsProxyUrl" className="block text-sm font-medium text-gray-300 mb-1">网络兼容性代理 URL (可选)</label>
                        <input
                            type="text"
                            id="corsProxyUrl"
                            placeholder="例如: https://my-proxy.com/"
                            value={settings.corsProxyUrl}
                            onChange={(e) => handleSettingsFieldChange('corsProxyUrl', e.target.value)}
                            className="w-full p-2 bg-gray-700 rounded-md"
                        />
                    </div>
                    <div className="flex items-center justify-between">
                        <label htmlFor="alwaysShowManualParseModal" className="text-gray-300">调试: 总是显示手动解析窗口</label>
                        <input
                            type="checkbox"
                            id="alwaysShowManualParseModal"
                            checked={settings.alwaysShowManualParseModal}
                            onChange={(e) => handleSettingsFieldChange('alwaysShowManualParseModal', e.target.checked)}
                            className={checkboxStyles}
                        />
                    </div>

                    <CollapsibleSection title="AI 调用模式">
                        <div className="p-2 bg-gray-900/50 rounded-lg space-y-3">
                            <select
                                value={settings.aiCallMode}
                                onChange={(e) => handleSettingsFieldChange('aiCallMode', e.target.value as AiCallMode)}
                                className="w-full p-2 bg-gray-700 rounded-md"
                            >
                                <option value={AiCallMode.Hybrid}>混合模式 (推荐)</option>
                                <option value={AiCallMode.Double}>二次调用 (平衡)</option>
                            </select>
                            <div className="flex items-center justify-between">
                                <label htmlFor="hybridModeStreamNarrative" className="text-gray-300">混合模式下流式传输叙事</label>
                                <input
                                type="checkbox"
                                id="hybridModeStreamNarrative"
                                checked={settings?.hybridModeStreamNarrative ?? true}
                                onChange={(e) => handleSettingsFieldChange('hybridModeStreamNarrative', e.target.checked)}
                                className={checkboxStyles}
                                disabled={settings.aiCallMode !== AiCallMode.Hybrid}
                                />
                            </div>
                            <div className="flex items-center justify-between">
                                <label htmlFor="enableCalculationHelperAi" className="text-gray-300">
                                启用计算助手AI (多AI协作链) <span className="text-yellow-400 text-xs">(测试中)</span>
                                </label>
                                <input
                                type="checkbox"
                                id="enableCalculationHelperAi"
                                checked={settings?.enableCalculationHelperAi ?? false}
                                onChange={(e) => handleHybridModeCheckboxChange('enableCalculationHelperAi', e.target.checked)}
                                className={checkboxStyles}
                                disabled={settings.aiCallMode !== AiCallMode.Hybrid}
                                />
                            </div>
                            <div className="flex items-center justify-between">
                                <label htmlFor="enableFunctionCallingMode" className="text-gray-300">
                                启用函数调用模式 (实验性)
                                </label>
                                <input
                                type="checkbox"
                                id="enableFunctionCallingMode"
                                checked={settings?.enableFunctionCallingMode ?? false}
                                onChange={(e) => handleHybridModeCheckboxChange('enableFunctionCallingMode', e.target.checked)}
                                className={checkboxStyles}
                                disabled={settings.aiCallMode !== AiCallMode.Hybrid}
                                />
                            </div>
                            {settings.aiCallMode === AiCallMode.Hybrid && (
                                <div className="pt-3 mt-3 border-t border-gray-700 space-y-3">
                                    <h4 className="text-sm font-medium text-gray-400">混合模式专用模型 (可选)</h4>
                                    <div>
                                        <label htmlFor="hybridPlanningModel" className="block text-sm text-gray-300 mb-1">规划模型</label>
                                        <select id="hybridPlanningModel" value={settings.defaultHybridPlanningModelId || ''} onChange={(e) => handleSettingsFieldChange('defaultHybridPlanningModelId', e.target.value || null)} className="w-full p-2 bg-gray-700 rounded-md text-sm"><option value="">使用默认文本模型</option>{planningModels.map(m => <option key={m.id} value={m.id}>{m.displayName}</option>)}</select>
                                    </div>
                                    <div>
                                        <label htmlFor="hybridNarrativeModel" className="block text-sm text-gray-300 mb-1">叙事模型</label>
                                        <select id="hybridNarrativeModel" value={settings.defaultHybridNarrativeModelId || ''} onChange={(e) => handleSettingsFieldChange('defaultHybridNarrativeModelId', e.target.value || null)} className="w-full p-2 bg-gray-700 rounded-md text-sm"><option value="">使用默认文本模型</option>{narrativeModels.map(m => <option key={m.id} value={m.id}>{m.displayName}</option>)}</select>
                                    </div>
                                    <div>
                                        <label htmlFor="hybridStatusModel" className="block text-sm text-gray-300 mb-1">状态/数据模型</label>
                                        <select id="hybridStatusModel" value={settings.defaultHybridStatusModelId || ''} onChange={(e) => handleSettingsFieldChange('defaultHybridStatusModelId', e.target.value || null)} className="w-full p-2 bg-gray-700 rounded-md text-sm"><option value="">使用默认文本模型</option>{statusModels.map(m => <option key={m.id} value={m.id}>{m.displayName}</option>)}</select>
                                    </div>
                                </div>
                            )}
                            {settings.aiCallMode === AiCallMode.Hybrid && settings?.enableCalculationHelperAi && (
                                <div className="flex items-center justify-between pl-6 mt-2">
                                <label htmlFor="showCalculationHelperAiPlan" className="text-gray-400 text-sm">
                                    调试: 显示计算助手规划
                                </label>
                                <input
                                    type="checkbox"
                                    id="showCalculationHelperAiPlan"
                                    checked={settings?.showCalculationHelperAiPlan ?? false}
                                    onChange={(e) => handleSettingsFieldChange('showCalculationHelperAiPlan', e.target.checked)}
                                    className={smallCheckboxStyles}
                                />
                                </div>
                            )}
                            {settings.aiCallMode === AiCallMode.Hybrid && settings?.enableFunctionCallingMode && (
                                <div className="flex items-center justify-between pl-6 mt-2">
                                <label htmlFor="showFunctionCallDebug" className="text-gray-400 text-sm">
                                    调试: 显示函数调用日志
                                </label>
                                <input
                                    type="checkbox"
                                    id="showFunctionCallDebug"
                                    checked={settings?.showFunctionCallDebug ?? false}
                                    onChange={(e) => handleSettingsFieldChange('showFunctionCallDebug', e.target.checked)}
                                    className={smallCheckboxStyles}
                                />
                                </div>
                            )}
                        </div>
                    </CollapsibleSection>
                </div>
            </CollapsibleSection>

        </div>

        <div className="mt-12 flex flex-col sm:flex-row justify-end gap-4" data-guide-id="save-settings-btn-container">
          <button onClick={onBack} className="px-6 py-3 bg-gray-600 hover:bg-gray-700 rounded-md shadow-md transition-transform transform hover:scale-105">{cameFromGame ? '返回游戏' : '返回主菜单'}</button>
          <button onClick={handleSaveSettings} className="px-6 py-3 bg-green-600 hover:bg-green-700 text-white font-semibold rounded-md shadow-md transition-transform transform hover:scale-105">保存所有设置</button>
        </div>
      </div>
      <Modal isOpen={isChannelModalOpen} onClose={() => setIsChannelModalOpen(false)} title={editingChannel ? '编辑 API 渠道' : '添加 API 渠道'}>
        <div className="space-y-4">
            <div><label className="block text-sm font-medium text-gray-300 mb-1">渠道名称</label><input type="text" name="name" value={currentChannelForm.name || ''} onChange={handleChannelFormChange} className="w-full p-2 bg-gray-700 rounded" placeholder="例如: OpenAI, Mistral API"/></div>
            <div><label className="block text-sm font-medium text-gray-300 mb-1">API Base URL</label><input type="text" name="baseUrl" value={currentChannelForm.baseUrl || ''} onChange={handleChannelFormChange} className="w-full p-2 bg-gray-700 rounded" placeholder="例如: https://api.openai.com/v1/chat/completions" /></div>
            <div><label className="block text-sm font-medium text-gray-300 mb-1">API 密钥</label><input type="password" name="apiKey" value={currentChannelForm.apiKey || ''} onChange={handleChannelFormChange} className="w-full p-2 bg-gray-700 rounded" placeholder="sk-..." /></div>
            <div className="flex justify-end pt-4 space-x-2"><button onClick={() => setIsChannelModalOpen(false)} className="px-4 py-2 bg-gray-600 hover:bg-gray-500 rounded-md text-sm">取消</button><button onClick={handleSaveChannel} className="px-4 py-2 bg-blue-600 hover:bg-blue-500 rounded-md text-sm">保存渠道</button></div>
        </div>
      </Modal>
      <Modal isOpen={isModelModalOpen} onClose={() => setIsModelModalOpen(false)} title={editingModel ? '编辑模型' : '添加模型'}>
         <div className="space-y-4">
            <div><label className="block text-sm font-medium text-gray-300 mb-1">显示名称</label><input type="text" name="displayName" value={currentModelForm.displayName || ''} onChange={handleModelFormChange} className="w-full p-2 bg-gray-700 rounded" placeholder="例如: GPT-4o Mini"/></div>
            <div><label className="block text-sm font-medium text-gray-300 mb-1">API 模型名称</label><input type="text" name="apiModelName" value={currentModelForm.apiModelName || ''} onChange={handleModelFormChange} className="w-full p-2 bg-gray-700 rounded" placeholder="例如: gpt-4o-mini"/></div>
            <div><label className="block text-sm font-medium text-gray-300 mb-1">API 渠道</label><select name="apiChannelId" value={currentModelForm.apiChannelId || ''} onChange={handleModelFormChange} className="w-full p-2 bg-gray-700 rounded">{settings.apiChannels.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}</select></div>
            <div><label className="block text-sm font-medium text-gray-300 mb-1">模型用途</label><select name="purpose" value={currentModelForm.purpose || 'general'} onChange={handleModelFormChange} className="w-full p-2 bg-gray-700 rounded">{modelPurposeOptions.map(opt => <option key={opt.value} value={opt.value}>{opt.label}</option>)}</select></div>
            <div><label className="block text-sm font-medium text-gray-300 mb-1">温度 (0-2)</label><input type="number" name="temperature" value={currentModelForm.temperature || 0} onChange={handleModelFormChange} className="w-full p-2 bg-gray-700 rounded" step="0.1" min="0" max="2"/></div>
            <div><label className="block text-sm font-medium text-gray-300 mb-1">最大Token数</label><input type="number" name="maxTokens" value={currentModelForm.maxTokens || 0} onChange={handleModelFormChange} className="w-full p-2 bg-gray-700 rounded" step="64" min="1"/></div>
            <div className="flex justify-end pt-4 space-x-2"><button onClick={() => setIsModelModalOpen(false)} className="px-4 py-2 bg-gray-600 hover:bg-gray-500 rounded-md text-sm">取消</button><button onClick={handleSaveModel} className="px-4 py-2 bg-blue-600 hover:bg-blue-500 rounded-md text-sm">保存模型</button></div>
        </div>
      </Modal>
    </div>
  );
};

export default SettingsScreen;